#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include "net/tcp_client.h"
#include "net/udp_client.h"
#include "net/kcp_client.h"

using boost::asio::ip::tcp;
using boost::asio::ip::udp;

void runTcpClient() {
    // 创建客户端实例
    auto client = std::make_shared<net::TcpClient>();

    // 启动客户端 I/O 线程
    client->start();

    // 定义连接成功后的回调逻辑
    auto connect_handler = [](net::Connection::Ptr conn, const boost::system::error_code& ec) {
        if (!ec && conn) {
            std::cout << "Client successfully connected to server." << std::endl;

            conn->setCodec(std::make_unique<net::SimpleMessageCodec>());

            // 设置消息接收回调
            conn->setMessageReceiver(
                    [](net::Connection::Ptr sender, const net::Buffer& msg, size_t length) {
                        std::string msgStr = std::string(msg.begin(), msg.end());
                        std::cout << "Client received: " << msgStr << std::endl;
                        // 收到回显后，可以再次发送或关闭
                        if (msgStr.find("Hello") != std::string::npos) {
                            sender->send("This is the second message from client.");
                        } else {
                            // sender->close();
                        }
                    });

            // 设置错误回调
            conn->setErrorHandler(
                    [](net::Connection::Ptr, const boost::system::error_code& error) {
                        if (error != boost::asio::error::eof) {
                            std::cerr << "Client connection error: " << error.message() << std::endl;
                        } else {
                            std::cout << "Client connection closed cleanly by peer." << std::endl;
                        }
                    });

            // 第一次发送数据 (将自动通过 Codec 编码)
            conn->send("Hello, TcpServer! This is client.");

        } else {
            std::cerr << "Client failed to connect: " << ec.message() << std::endl;
        }
    };

    std::cout << "Client attempting to connect to 127.0.0.1:8080..." << std::endl;

    // 发起连接
    client->connect("127.0.0.1", 8080, connect_handler);

    // 主线程等待一段时间，让客户端完成工作
    std::this_thread::sleep_for(std::chrono::seconds(2));
    client->getConnection()->send("next second");
    std::this_thread::sleep_for(std::chrono::seconds(10));
    // 停止客户端
    client->stop();
}

void runUdpClient() {
    try {
        boost::asio::io_context ioContext;

        // 服务器地址和端口（假设您的服务器运行在本地，端口 9000）
        const std::string SERVER_IP = "127.0.0.1";
        const short SERVER_PORT = 9000;

        // 实例化客户端
        net::UdpClient client(ioContext, SERVER_IP, SERVER_PORT);

        // --- 核心：设置接收消息回调 ---
        client.setReceiveCallback([](const std::string& message, std::size_t size) {
            std::cout << "[RECV] Server Response (" << size << " bytes): " << message << std::endl;
        });

        // --- 客户端业务逻辑：发送消息 ---

        // 1. 立即发送第一条消息（触发服务器的 onConnect/新会话创建）
        client.sendMessage("Hello Server, this is Client 1.");

        // 2. 延迟发送第二条消息（使用定时器模拟后续操作）
        boost::asio::steady_timer timer(ioContext, std::chrono::seconds(2));
        timer.async_wait([&client](const boost::system::error_code& ec) {
            if (!ec) {
                client.sendMessage("Ping from Client 1 at 2 seconds.");
            }
        });

        // 3. 延迟发送第三条消息
        boost::asio::steady_timer timer2(ioContext, std::chrono::seconds(5));
        timer2.async_wait([&client](const boost::system::error_code& ec) {
            if (!ec) {
                client.sendMessage("Final message from Client 1 at 5 seconds.");
            }
        });

        // 运行 ioContext，处理异步操作
        ioContext.run();

    } catch (std::exception& e) {
        std::cerr << "Fatal Exception: " << e.what() << std::endl;
    }
}

void runKcpClient() {
    try {
        boost::asio::io_context ioContext;

        const std::string SERVER_IP = "127.0.0.1";
        const short SERVER_PORT = 9000;
        const net::ConvIdType CLIENT_CONV_ID = 100; // 必须与服务器分配的 ID 一致

        // 实例化客户端
        net::KcpClient client(ioContext, SERVER_IP, SERVER_PORT, CLIENT_CONV_ID);

        // --- 设置回调 ---
        client.setReceiveCallback([](const std::string& message, std::size_t size) {
            std::cout << "[KCP RECV] Server Message (" << size << " bytes): " << message << std::endl;
        });

        client.setErrorCallback([](const boost::system::error_code& ec) {
            std::cerr << "[KCP EVENT] Client Error: " << ec.message() << std::endl;
        });

        // --- 客户端业务逻辑：发送 KCP 消息 ---

        // KCP 消息发送
        client.sendMessage("Initial KCP handshake message.");

        // 使用定时器发送多条消息，以测试 KCP 的可靠性
        boost::asio::steady_timer timer(ioContext, std::chrono::milliseconds(500));
        timer.async_wait([&client](const boost::system::error_code& ec) {
            if (!ec) {
                // KCP 会保证消息顺序和可靠性
                for (int i = 1; i <= 5; ++i) {
                    client.sendMessage("Reliable data packet number " + std::to_string(i));
                }
            }
        });

        // 运行 ioContext
        ioContext.run();

    } catch (std::exception& e) {
        std::cerr << "Fatal Exception: " << e.what() << std::endl;
    }
}

int main(int argc, char* argv[]) {
    // runTcpClient();
    // runUdpClient();
    runKcpClient();
    return 0;
}